/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.system.service.impl;


import com.koron.common.domain.DataBean;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.system.domain.DictData;
import com.koron.system.domain.DictType;
import com.koron.system.mapper.DictDataMapper;
import com.koron.system.mapper.DictTypeMapper;
import com.koron.system.service.api.DictDataService;
import com.koron.system.utils.BusinessCode;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;
import org.swan.bean.MessageBean;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Service
public class DictDataServiceImpl implements DictDataService, InitializingBean {

    private final static  Logger logger = LoggerFactory.getLogger(DictDataServiceImpl.class);

    private static Map<String, DictData> cacheMap = new ConcurrentHashMap<>();

    @Resource(name = "primaryDataSource")
    private DataSource primaryDataSource;

    @Override
    public void afterPropertiesSet() throws Exception {
        try (SessionFactory factory = new SessionFactory()) {
            DictDataMapper mapper = factory.getMapper(DictDataMapper.class);
            List<DictData> dataList = mapper.queryAll(null, null, null, null);
            if (!dataList.isEmpty()) {
                cacheMap.putAll(dataList.stream().collect(Collectors.toMap(DictData::getId, d -> d)));
            }
        }
    }

    @Override
    public MessageBean<Integer> save(DictData dictData) {
        MessageBean<Integer> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory();) {
            DictDataMapper mapper = factory.getMapper(DictDataMapper.class);
            DictTypeMapper typeMapper = factory.getMapper(DictTypeMapper.class);
            DictType type = typeMapper.queryByKey(dictData.getDictKey());
            if (null == type) {
                msg.setCode(BusinessCode.DICTDATA_TYPEKEY_NOT_FOUNT.getCode());
                msg.setDescription(BusinessCode.DICTDATA_TYPEKEY_NOT_FOUNT.getDescription());
                return msg;
            }
            Integer value = 0;
            if (StringUtils.isEmpty(dictData.getId())) {
                //新增操作
                //判断同一字典类型下是否有同标签的列表
                List<DictData> isExitList = mapper.queryAll(dictData.getDictLabel(), dictData.getDictKey(), null, null);
                if (isExitList.size() > 0) {
                    msg.setCode(BusinessCode.DICTDATA_SIMPLEKEY_DOUBLE_LABEL.getCode());
                    msg.setDescription(BusinessCode.DICTDATA_SIMPLEKEY_DOUBLE_LABEL.getDescription());
                    return msg;
                }
                dictData.setId(DefaultIdGenerator.getInstance().generateLongId());
                dictData.setAddTime(dictData.getUpdateTime());
                dictData.setAddUser(dictData.getUpdateUser());
                dictData.setReferenceCount(0L);
                value = mapper.insert(dictData);
            } else {
                //修改操作
                List<DictData> isExitList = mapper.queryAll(dictData.getDictLabel(), dictData.getDictKey(), null, null);
                for (DictData data : isExitList) {
                    if (!data.getId().equals(dictData.getId())) {
                        msg.setCode(BusinessCode.DICTDATA_SIMPLEKEY_DOUBLE_LABEL.getCode());
                        msg.setDescription(BusinessCode.DICTDATA_SIMPLEKEY_DOUBLE_LABEL.getDescription());
                        return msg;
                    }
                }
                value = mapper.update(dictData);
            }
            if (value > 0) {
                cacheMap.put(dictData.getId(), dictData);
                msg.setCode(BusinessCode.SUCCESS.getCode());
                msg.setDescription("保存字典数据成功");
                msg.setData(value);
                return msg;
            } else {
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("保存字典数据失败");
                msg.setData(value);
                return msg;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }

    @Override
    public MessageBean<Integer> batchUpdate(List<DictData> dictDataList) {
        MessageBean<Integer> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory();) {
            DictDataMapper mapper = factory.getMapper(DictDataMapper.class);
            DictTypeMapper typeMapper = factory.getMapper(DictTypeMapper.class);
            for (DictData data : dictDataList) {
                List<DictData> isExitList = mapper.queryAll(data.getDictLabel(), data.getDictKey(), null, null);
                if (isExitList.size() > 0) {
                    msg.setCode(BusinessCode.DICTDATA_SIMPLEKEY_DOUBLE_LABEL.getCode());
                    msg.setDescription("字典数据标签名称为" + data.getDictLabel() + "同一字典类型下的字典数据重复");
                    return msg;
                }
                DictType type = typeMapper.queryByKey(data.getDictKey());
                if (null == type) {
                    msg.setCode(BusinessCode.DICTDATA_TYPEKEY_NOT_FOUNT.getCode());
                    msg.setDescription("字典数据标签名称为" + data.getDictLabel() + "不存在对应的字典类型key,无法保存");
                    return msg;
                }
            }
            Integer value = mapper.batchUpdate(dictDataList);
            if (value > 0) {
                cacheMap.putAll(dictDataList.stream().collect(Collectors.toMap(DictData::getId, d -> d)));
                msg.setCode(BusinessCode.SUCCESS.getCode());
                msg.setDescription("批量修改字典数据成功");
                return msg;
            } else {
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("批量修改字典数据失败");
                return msg;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }
    }

    @Override
    public MessageBean<Integer> batchDelete(List<String> idList) {
        MessageBean<Integer> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory();) {
            DictDataMapper mapper = factory.getMapper(DictDataMapper.class);
            List<String> delIdList = new ArrayList<>();
            StringBuilder description = new StringBuilder();
            for (String id : idList) {
                DictData data = queryOne(id).getData();
                if (null != data && data.getReferenceCount() <= 0) {
                    delIdList.add(id);
                } else {
                    description.append(data == null ? "" : data.getDictLabel());
                }
            }
            if (null == delIdList || delIdList.size() <= 0) {
                msg.setCode(BusinessCode.DICTDATA_IS_REFERENCED.getCode());
                msg.setDescription(BusinessCode.DICTDATA_IS_REFERENCED.getDescription());
                return msg;
            }
            Integer value = mapper.batchDetele(delIdList);
            if (value > 0) {
                delIdList.forEach(id -> cacheMap.remove(id));
                msg.setCode(BusinessCode.SUCCESS.getCode());
                msg.setDescription("批量删除字典数据成功" + (StringUtils.isEmpty(description.toString()) ? "" :
                        "但选择中字典数据中标签名称为：" + description.toString() + "在其他地方被引用，无法删除"));
                msg.setData(value);
                return msg;
            } else {
                msg.setCode(BusinessCode.FAILURE.getCode());
                msg.setDescription("批量删除字典数据失败");
                msg.setData(value);
                return msg;
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }

    @Override
    public MessageBean<DictData> queryOne(String id) {
        MessageBean<DictData> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory();) {
            DictDataMapper mapper = factory.getMapper(DictDataMapper.class);
            DictData data = mapper.queryOne(id);
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription("获取字典数据详情成功");
            msg.setData(data);
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }
    }

    @Override
    public MessageBean<DataBean<DictData>> queryAll(String dictLabel, String dictKey, Integer start, Integer rows) {
        MessageBean<DataBean<DictData>> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory();) {
            DictDataMapper mapper = factory.getMapper(DictDataMapper.class);
            List<DictData> list = mapper.queryAll(dictLabel, dictKey, start, rows);
            Integer totalNumber = mapper.countTotal(dictLabel, dictKey);
            rows = rows == null ?totalNumber:( rows <= 0 ? 1 : rows);
            Integer totalPage = (totalNumber > rows) ? (totalNumber % rows == 0 ? totalNumber / rows : totalNumber / rows + 1) : 1;
            DataBean<DictData> dataBean = new DataBean<>();
            dataBean.setList(list);
            dataBean.setTotalPage(totalPage);
            dataBean.setTotalNumber(totalNumber);
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription("获取字典数据列表成功");
            msg.setData(dataBean);
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return null;
    }

    @Override
    public DictData matchDictData(String dictTypeName, String dictLabel) {
        try (SessionFactory factory = new SessionFactory()) {
            DictData data = factory.getMapper(DictDataMapper.class).matchDictData(dictTypeName, dictLabel);
            return data;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage(),e);
            return null;
        }
    }

    @Override
    public Map<String, DictData> getCacheMap() {
        return cacheMap;
    }

}
